package com.letu.core.excel.analyze;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.letu.core.excel.bean.*;
import com.letu.core.excel.exception.ExcelColumnAnalyzeException;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ClassName ExcelAnalyze
 * @Description excel解析，基于hutool进行二次包装
 * @Author yuwx
 * @Date 2021/9/4 15:25
 * @Version 1.0
 **/
@Slf4j
public class ExcelAnalyze<T> {
    private  ExcelReader reader;
    private ExcelAnalyze() {
    }
    public ExcelAnalyze(ExcelReader reader) {
        this.reader = reader;
    }


    /**
    *Description key 行， value  列
    *@Date 11:13 2021/9/6
    *@return
    *@Author yuwx
    **/
    public ExcelAnalyzeResult<T> analyze(String path, Class<T> targetClass) {

        List<T> targetResultList = new ArrayList<>();
        List<ExcelAnalyzeExceptionResult> exceptionResultList = new ArrayList<>();
        List<List<Object>> list = ExcelUtil.getReader(reader.read(path), 0).read(1);
        List<ExcelField> excelFieldList = getExcelField(targetClass);
        AtomicInteger tipRowIndex = new AtomicInteger(2);
        list.stream().forEach(rowList -> {
            tipRowIndex.incrementAndGet();
            try {
                T target = analyzeRowToTarget(excelFieldList, rowList, targetClass.newInstance());
                targetResultList.add(target);
            } catch (InstantiationException e) {
                exceptionResultList.add(new ExcelAnalyzeExceptionResult(tipRowIndex.get(), -1, "未知异常"));
            } catch (IllegalAccessException e) {
                exceptionResultList.add(new ExcelAnalyzeExceptionResult(tipRowIndex.get(), -1, "未知异常"));
            } catch (ExcelColumnAnalyzeException excelColumnAnalyzeException) {
                exceptionResultList.add(new ExcelAnalyzeExceptionResult(tipRowIndex.get(),
                        excelColumnAnalyzeException.getColumnIndex(), excelColumnAnalyzeException.getMessage()));
            }

        });
        return new ExcelAnalyzeResult<>(targetResultList, exceptionResultList);
    }

    public static void main(String[] args) {
        List<String> list = Stream.of("1", "2", "3", "4").filter(a -> !"2".equals(a)).collect(Collectors.toList());
        System.out.println(list);
    }
    /**
    *Description 解析行数据到目标对象
    *@Date 11:59 2021/9/6
    *@param excelFieldList 目标对象字段
    *@param rowValueList 行数据
    *@param target 目标对象
    *@return T
    *@Author yuwx
    **/
    private T analyzeRowToTarget(List<ExcelField> excelFieldList, List<Object> rowValueList, T target) {
        AtomicInteger tipColumnIndex = new AtomicInteger(1);
        excelFieldList.stream().forEach(excelField -> {
            tipColumnIndex.incrementAndGet();
            Integer columnIndex = excelField.getColumnIndex();
            Field field = excelField.getField();
            Class fieldClass = excelField.getFieldClass();
            if (columnIndex >= rowValueList.size()) {
                return;
            }
            Object fieldValue = rowValueList.get(columnIndex);
            try {
                if (Boolean.class.getName().equals(fieldClass.getName())) {
                    JudgeTypeEnum judgeTypeEnum = Convert.toEnum(JudgeTypeEnum.class, fieldValue);
                    BeanUtil.setFieldValue(target, field.getName(), JudgeTypeEnum.convertBoolean(judgeTypeEnum));
                } else if (excelField.getFieldClass().isEnum()) {
                    BeanUtil.setFieldValue(target, field.getName(), Convert.toEnum(fieldClass, fieldValue));
                } else {
                    BeanUtil.setFieldValue(target, field.getName(), Convert.convert(fieldClass, fieldValue));
                }
            }  catch (Exception e) {
                throw new ExcelColumnAnalyzeException(tipColumnIndex.get(), fieldValue.toString());
            }
        });
        return target;
    }
    /**
    *Description 解析目标类定义的Excel结构，获取序号，字段
    *@Date 11:19 2021/9/6
    *@param clazz
    *@Author yuwx
    **/
    private List<ExcelField> getExcelField(Class clazz) {
        Field[]  fields =ClassUtil.getDeclaredFields(clazz);
        if (null == fields && fields.length == 0) {
            return Collections.emptyList();
        }
        List<ExcelField> excelFieldList = new ArrayList<>(fields.length);
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            if (!field.isAnnotationPresent(ExcelFiledAnnotation.class)) {
                continue;
            }
            ExcelFiledAnnotation excelFiledAnnotation = field.getAnnotation(ExcelFiledAnnotation.class);
            excelFieldList.add(ExcelField.builder().columnIndex(excelFiledAnnotation.value()).fieldClass(field.getType()).field(field).build());
        }
        return excelFieldList;
    }

}
